package com.foo.designpattern.templatemethod;

import junit.framework.TestCase;

/**
 * com.foo.designpattern.templatemethod
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-05-13 15:26.
 *
 * @Description 测试类：模板方法模式(TemplateMethod)
 * <p/>
 * 模板方法模式：模板方法模式是类的行为模式。准备一个抽象类，将部分逻辑以具体方法以及具体构造函数的形式实现，
 * 然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法，从而对剩余的逻辑有不同的实现。
 * 比如定义一个操作中的算法的骨架，将步骤延迟到子类中。模板方法使得子类能够不去改变一个算法的结构即可重定义算法的某些特定步骤。
 * <p/>
 * 模板方法模式中涉及两种角色：
 * 1、抽象模板角色(Abstract Template):实现了模板方法，定义了算法的骨架。
 * 2、具体模板角色(Concrete Template):实现了抽象模板中的抽象方法，已完成完整的算法。
 * <p/>
 * 模板方法模式的优点：
 * 1、模板方法模式通过把不变的行为搬移到父类，去除了子类中的重复代码；
 * 2、子类实现算法的某些细节，有助于算法的扩展；
 * 3、通过一个父类调用子类实现的操作，通过子类扩展增加新的行为，符合"开闭原则"。
 * <p/>
 * 模板方法模式的缺点：
 * 每个不同的实现都需要定义一个子类，这回导致类的个数的增加，设计更加抽象。
 * <p/>
 * 模板方法模式的适用场景：
 * 1、在某些类的算法中，用了相同的方法，造成代码的重复；
 * 2、控制子类扩展，子类必须遵守算法规则。
 * <p/>
 * 模板方法模式在Servlet中的应用：
 * Servlet 除了要在 web.xml 中做相应的配置外，还需继承 HttpServlet 这个抽象类。
 * HttpService 类提供了一个 service() 方法，这个方法调用七个 doXXX() 方法中的一个或几个，完成对客户端的响应。
 * 这些 doXXX() 方法需要由 HttpServlet 的具体子类提供，因此这是典型的模板方法模式。
 */

public class TemplateMethodTestCase extends TestCase {
    public void testTemplateMethod() {
        System.out.println("= = = = ↓↓↓模版模式，测试开始↓↓↓ = = = =");

        /**
         * 生产不同的手机只是修改具体模板(ConcreteTemplate)就可以了
         */
        // 生产具体模板A定义的手机
        AbstractTemplate abstractTemplateA = new ConcreteTemplateA();
        abstractTemplateA.makeMobile();
        // 生产具体模板B定义的手机
        AbstractTemplate abstractTemplateB = new ConcreteTemplateB();
        abstractTemplateB.makeMobile();

        System.out.println("= = = = ↑↑↑模板模式，测试结束↑↑↑ = = = =");
    }
}
